﻿using ZhiAo.BaseFramework.Library.INIFile;
using System;
using System.Data;
using System.Text;
using System.Threading;

namespace ZhiAo.BaseFramework.DBConnection
{
    public class DB
    {
        private bool _DBScriptLog;
        private ConnectionType _DBType;
        public static int CommandTimeout = 600;
        private string FConnectionString;
        private I_DB myDB;

        public DB()
        {
            this.FConnectionString = "";
            this._DBScriptLog = false;
            switch (ConnInfo.DBConnType)
            {
                case ConnectionType.SQL:
                    this.myDB = new SQLDB(ConnInfo.GetConnString(), ConnInfo.DBConnType);
                    break;

                case ConnectionType.OLE:
                    this.myDB = new OleDB(ConnInfo.GetConnString(), ConnInfo.DBConnType);
                    break;

                case ConnectionType.ORA:
                    this.myDB = new OraDB(ConnInfo.GetConnString(), ConnectionType.ORA);
                    break;

                default:
                    this.myDB = new OleDB(ConnInfo.GetConnString(), ConnInfo.DBConnType);
                    break;
            }
            this._DBType = ConnInfo.DBConnType;
            this.FConnectionString = ConnInfo.GetConnString();
        }

        public DB(string ConnName)
        {
            this.FConnectionString = "";
            this._DBScriptLog = false;
            ConnDictInfo info = (ConnDictInfo)ConnInfo.conn[ConnName];
            if (info != null)
            {
                string str = info.type.ToString();
                if (str == null)
                {
                    goto Label_009B;
                }
                if (!(str == "OLE"))
                {
                    if (str == "SQL")
                    {
                        this.myDB = new SQLDB(info.conn, ConnectionType.SQL);
                        return;
                    }
                    if (str == "ORA")
                    {
                        return;
                    }
                    goto Label_009B;
                }
                this.myDB = new OleDB(info.conn, ConnectionType.OLE);
            }
            return;
        Label_009B:
            this.myDB = new OleDB(info.conn, ConnectionType.SQL);
        }

        public DB(string Connection, ConnectionType ConnType)
        {
            this.FConnectionString = "";
            this._DBScriptLog = false;
            this.FConnectionString = Connection;
            this._DBType = ConnType;
            switch (ConnType)
            {
                case ConnectionType.SQL:
                    this.myDB = new SQLDB(Connection, ConnType);
                    break;

                case ConnectionType.OLE:
                    this.myDB = new OleDB(Connection, ConnType);
                    break;

                case ConnectionType.ORA:
                    this.myDB = new OraDB(Connection, ConnectionType.ORA);
                    break;

                default:
                    this.myDB = new OleDB(Connection, ConnType);
                    break;
            }
        }

        private bool CheckContainPrimaryKey(string strFieldName, DataTable drData)
        {
            bool flag = false;
            for (int i = 0; i < drData.PrimaryKey.Length; i++)
            {
                flag = drData.PrimaryKey[i].ColumnName == strFieldName;
                if (flag)
                {
                    return flag;
                }
            }
            return flag;
        }

        public void Close()
        {
        }

        public void Commit(object oDBTransaction)
        {
            this.myDB.Commit(oDBTransaction);
        }

        public object CreateParameter(string strName, object oValue, ParameterDirection dpType, int iSize)
        {
            return this.myDB.CreateParameter(strName, oValue, dpType, iSize);
        }

        public void CreateSqlScript(DataTable dtData, StringBuilder stringBuilder)
        {
            string str = "";
            string columnsString = this.GetColumnsString(dtData);
            for (int i = 0; i < dtData.Rows.Count; i++)
            {
                DataRow drData = dtData.Rows[i];
                str = "";
                if (drData.RowState == DataRowState.Added)
                {
                    string dataValues = this.GetDataValues(drData);
                    str = " Insert into " + dtData.TableName + "(" + columnsString + ") values(" + dataValues + ");";
                }
                if (drData.RowState == DataRowState.Deleted)
                {
                    str = " delete from " + dtData.TableName + " where " + dtData.PrimaryKey[0].ColumnName + "='" + drData[dtData.PrimaryKey[0].ColumnName].ToString() + "';";
                }
                if (drData.RowState == DataRowState.Modified)
                {
                    string fieldVsValue = this.GetFieldVsValue(drData);
                    str = " update " + dtData.TableName + " set " + fieldVsValue + " where " + dtData.PrimaryKey[0].ColumnName + "='" + drData[dtData.PrimaryKey[0].ColumnName].ToString() + "';";
                }
                if (str.Length != 0)
                {
                    stringBuilder.Append(str);
                }
            }
        }

        public object CreateTransaction()
        {
            return this.myDB.CreateTransaction();
        }



        public bool Execute(DataSet dsData)
        {
            StringBuilder stringBuilder = new StringBuilder();
            if ((this.ConnectionString.IndexOf("MSDAORA") > 0) || (this.myDB.ConnType == ConnectionType.ORA))
            {
                stringBuilder.Append("begin ");
            }
            for (int i = 0; i < dsData.Tables.Count; i++)
            {
                this.CreateSqlScript(dsData.Tables[i], stringBuilder);
            }
            if ((this.ConnectionString.IndexOf("MSDAORA") > 0) || (this.myDB.ConnType == ConnectionType.ORA))
            {
                stringBuilder.Append("end; ");
            }
            return this.Execute(stringBuilder.ToString(), true);
        }

        public bool Execute(DataTable dtData)
        {
            StringBuilder stringBuilder = new StringBuilder();
            if ((this.ConnectionString.IndexOf("MSDAORA") > 0) || (this.myDB.ConnType == ConnectionType.ORA))
            {
                stringBuilder.Append(" begin ");
            }
            this.CreateSqlScript(dtData, stringBuilder);
            if ((this.ConnectionString.IndexOf("MSDAORA") > 0) || (this.myDB.ConnType == ConnectionType.ORA))
            {
                stringBuilder.Append(" end; ");
            }
            return this.Execute(stringBuilder.ToString(), true);
        }

        public bool Execute(string SQL)
        {
            return this.Execute(SQL, false);
        }

        public void Execute(string strSql, object oDBTransaction)
        {
            this.myDB.Execute(strSql, oDBTransaction);
            if (this._DBScriptLog)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(this.LogEvent), strSql);
            }
        }


        public bool Execute(string SQL, bool IsNeedTransaction)
        {
            return this.Execute(SQL, IsNeedTransaction, null);
        }



        public bool Execute(string SQL, bool IsNeedTransaction, object Transaction)
        {
            return this.Execute(SQL, IsNeedTransaction, Transaction, CommandType.Text, null);
        }

        public bool Execute(string SQL, CommandType commandType, params object[] parameters)
        {
            return this.Execute(SQL, true, null, commandType, parameters);
        }

        public bool Execute(string SQL, bool IsNeedTransaction, object transaction, CommandType commandType, params object[] parameters)
        {
            if (this._DBScriptLog)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(this.LogEvent), SQL);
            }
            return this.myDB.Execute(SQL, IsNeedTransaction, transaction, commandType, parameters);
        }

        public void ExecuteProcedure(string strProcedureName, object[] oParameters)
        {
            this.myDB.ExecuteProcedure(strProcedureName, oParameters);
            if (this._DBScriptLog)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(this.LogEvent), strProcedureName);
            }
        }

        private string GetColumnsString(DataTable dtData)
        {
            string str = "";
            for (int i = 0; i < (dtData.Columns.Count - 1); i++)
            {
                str = str + dtData.Columns[i].ColumnName + ",";
            }
            return (str + dtData.Columns[dtData.Columns.Count - 1].ColumnName);
        }

        public DataReader GetDataReader(string strSQL)
        {
            return this.GetDataReader(strSQL, false);
        }

        public DataReader GetDataReader(string strSQL, bool IsNeedTransaction)
        {
            return this.GetDataReader(strSQL, IsNeedTransaction, null);
        }

        public DataReader GetDataReader(string strSQL, bool IsNeedTransaction, object transaction)
        {
            return this.GetDataReader(strSQL, IsNeedTransaction, transaction, CommandType.Text, null);
        }

        public DataReader GetDataReader(string strSQL, CommandType commandType, params object[] parameters)
        {
            return this.GetDataReader(strSQL, false, null, commandType, parameters);
        }

        public DataReader GetDataReader(string SQL, bool IsNeedTransaction, object transaction, CommandType commandType, params object[] parameters)
        {
            return this.myDB.GetDataReader(SQL, IsNeedTransaction, transaction, commandType, parameters);
        }

        public DataSet GetDataSet(string SQL)
        {
            return this.GetDataSet(SQL, "");
        }



        public DataSet GetDataSet(string SQL, string Alias)
        {
            return this.GetDataSet(SQL, Alias, false);
        }

        public DataSet GetDataSet(string SQL, string Alias, bool IsNeedTransaction)
        {
            return this.GetDataSet(SQL, Alias, IsNeedTransaction, null);
        }

        public DataSet GetDataSet(string SQL, string Alias, bool IsNeedTransaction, object transaction)
        {
            return this.GetDataSet(SQL, Alias, IsNeedTransaction, transaction, CommandType.Text, null);
        }

        public DataSet GetDataSet(string SQL, string Alias, CommandType commandType, params object[] parameters)
        {
            return this.myDB.GetDataSet(SQL, Alias, false, null, commandType, parameters);
        }

        public DataSet GetDataSet(string SQL, string Alias, bool IsNeedTransaction, object transaction, CommandType commandType, params object[] parameters)
        {
            DataSet set = this.myDB.GetDataSet(SQL, Alias, IsNeedTransaction, transaction, commandType, parameters);
            if (set == null)
            {
                throw new ApplicationException(this.myDB.ErrMessage);
            }
            return set;
        }

        public DataTable GetDataTable(string SQL, string strAlias)
        {
            return this.GetDataSet(SQL, strAlias).Tables[strAlias].Copy();
        }

        private string GetDataValues(DataRow drData)
        {
            string str = "";
            for (int i = 0; i < drData.Table.Columns.Count; i++)
            {
                str = str + "'" + drData[i].ToString() + "',";
            }
            return str.Substring(0, str.Length - 1);
        }

        public DataView GetDataView(string SQL)
        {
            return this.GetDataView(SQL, false);
        }

        public DataView GetDataView(string SQL, bool IsNeedTransaction)
        {
            return this.GetDataView(SQL, IsNeedTransaction, null);
        }

        public DataView GetDataView(string SQL, bool IsNeedTransaction, object transaction)
        {
            return this.GetDataView(SQL, IsNeedTransaction, transaction, CommandType.Text, null);
        }

        public DataView GetDataView(string SQL, CommandType commandType, params object[] parameters)
        {
            return this.GetDataView(SQL, false, null, commandType, parameters);
        }

        public DataView GetDataView(string SQL, bool IsNeedTransaction, object transaction, CommandType commandType, params object[] parameters)
        {
            DataView view = this.myDB.GetDataView(SQL, IsNeedTransaction, transaction, commandType, parameters);
            if (view == null)
            {
                throw new ApplicationException("Sql script excuted failed:" + this.myDB.ErrMessage);
            }
            return view;
        }

        public string GetFieldValue(string SQL)
        {
            return this.GetFieldValue(SQL, "");
        }

        public string GetFieldValue(string SQL, string FieldName)
        {
            return this.GetFieldValue(SQL, FieldName, false);
        }

        public string GetFieldValue(string SQL, string FieldName, bool IsNeedTransaction)
        {
            return this.GetFieldValue(SQL, FieldName, IsNeedTransaction, null);
        }

        public string GetFieldValue(string SQL, string FieldName, bool IsNeedTransaction, object transaction)
        {
            return this.GetFieldValue(SQL, FieldName, IsNeedTransaction, transaction, null);
        }

        public string GetFieldValue(string SQL, string FieldName, bool IsNeedTransaction, object transaction, params object[] parameters)
        {
            return this.myDB.GetFieldValue(SQL, FieldName, IsNeedTransaction, transaction, CommandType.Text, parameters);
        }

        private string GetFieldVsValue(DataRow drData)
        {
            string str = "";
            for (int i = 0; i < drData.Table.Columns.Count; i++)
            {
                if (!this.CheckContainPrimaryKey(drData.Table.Columns[i].ColumnName, drData.Table))
                {
                    string str3 = str;
                    str = str3 + drData.Table.Columns[i].ColumnName + "='" + drData[i].ToString() + "',";
                }
            }
            return str.Substring(0, str.Length - 1);
        }

        public object GetParameterValue(object oParameter)
        {
            return this.myDB.GetParameterValue(oParameter);
        }

        private void LogEvent(object arg)
        {
            try
            {
                INIWrapper.WriteINIValue(@"C:\dbconnectionlog.ini", "Log", Guid.NewGuid() + "--" + DateTime.Now.ToString(), arg.ToString());
            }
            catch
            {
            }
        }

        public void RollBack(object oDBTransaction)
        {
            this.myDB.RollBack(oDBTransaction);
        }

        public void UpdateOracleLongField(string strTableName, string strFieldName, string strValue, string strCondition)
        {
            string sQL = "update " + strTableName + " set " + strFieldName + "=? where " + strCondition;
            object[] parameters = new object[] { this.CreateParameter(strFieldName, strValue, ParameterDirection.Input, strValue.Length) };
            if (!this.Execute(sQL, CommandType.Text, parameters))
            {
                throw new ApplicationException(this.ErrMessage);
            }
        }

        public string ConnectionString
        {
            get
            {
                return this.FConnectionString;
            }
            set
            {
                this.FConnectionString = value;
            }
        }

        public bool DBScriptLog
        {
            get
            {
                return this._DBScriptLog;
            }
            set
            {
                this._DBScriptLog = value;
            }
        }

        public string ErrMessage
        {
            get
            {
                return this.myDB.ErrMessage;
            }
        }

        public bool IsOracleDB
        {
            get
            {
                return ((this._DBType == ConnectionType.ORA) || (this.ConnectionString.IndexOf("ORA") > 1));
            }
        }
    }
}

